package com.domainchen.framework.dispatcther;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.domainchen.framework.common.config.Global;
import com.domainchen.framework.common.util.JsonUtil;
import com.domainchen.framework.common.util.StringUtils;
import com.domainchen.framework.core.bean.Handler;
import com.domainchen.framework.core.bean.Param;
import com.domainchen.framework.core.bean.RtnData;
import com.domainchen.framework.core.bean.ViewModel;
import com.domainchen.framework.core.holder.BeanHolder;
import com.domainchen.framework.core.holder.ControllerHolder;
import com.domainchen.framework.core.holder.IocHolder;
import com.domainchen.framework.core.util.Reflections;
import com.domainchen.framework.core.util.RequestHolder;
import com.domainchen.framework.core.util.ServletHolder;
import com.domainchen.framework.core.util.UploadHolder;
import com.domainchen.framework.core.util.classUtil.HolderLoader;

/**
 * @author domainchen or cytxiamen@163.com
 * @version 创建时间：2016年3月11日 上午10:14:25
 * @类说明 请求转发器
 */
@WebServlet(urlPatterns = "/*", loadOnStartup = 0)
public class DispatcherServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	public void init(ServletConfig config) throws ServletException {
		// 初始化相关Hodler(Bean,Class,Controller,Ioc)
		HolderLoader.init();
		// 获取 ServletContext 对象(注册Servlet)
		ServletContext servletContext = config.getServletContext();
		
		// 注册处理静态资源的默认Servlet
		ServletRegistration defaultServlet = servletContext.getServletRegistration("default");
		defaultServlet.addMapping("/favicon.ico");
		defaultServlet.addMapping(Global.getAppAssertPath() + "*");
	      
		// 注册处理Jsp的Servlet
		ServletRegistration jspServlet = servletContext.getServletRegistration("jsp");
		jspServlet.addMapping(Global.getAppDefaultPath());
		jspServlet.addMapping(Global.getAppJspPath() + "*");

		// 上传组件初始化对象
		UploadHolder.init(servletContext);
	}

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		ServletHolder.init(request, response);
		try {
			String requestMethod = request.getMethod().toLowerCase();
			String requestPath = request.getPathInfo();
			if (requestPath.equals("/favicon.ico")) {
				return;
			}

			Handler handler = ControllerHolder.getHandler(requestMethod, requestPath);
			if (null != handler) {
				// 获取Controller类及其实例
				Class<?> controllerClass = handler.getControllerClass();
				Object controllerBean = BeanHolder.getBean(controllerClass);

				// 创建请求参数对象
				Param param;
				if (UploadHolder.isMultipart(request)) {
					param = UploadHolder.createParam(request);
				} else {
					param = RequestHolder.createParam(request);
				}
				// 调用Action 方法
				Object result = null;
				Method actionMethod = handler.getActionMethod();
				//null==param||StringUtils.isEmpty(param.toString())
				if (param.isEmpty()) {
					result = Reflections.invokeMethod(controllerBean, actionMethod);
				} else {
					result = Reflections.invokeMethod(controllerBean, actionMethod, param);
				}
				// 处理Action 方法返回值
				// 视图
				if (result instanceof ViewModel) {
					// 返回JSP 页面
					ViewModel viewModel = (ViewModel) result;
					handleViewModleResult(viewModel, request, response);
				} else if (result instanceof RtnData) {
					RtnData rtnData = (RtnData) result;
					// 返回Json 数据
					handleRtnDataResult(rtnData, response);
				}
			}else{
				ViewModel viewModel =new ViewModel(Global.getAppDefaultPath());
				handleViewModleResult(viewModel, request, response);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			ServletHolder.destory();
		}
	}

	/**
	 * 返回视图
	 * 
	 * @param viewModel
	 * @param request
	 * @param response
	 */
	private void handleViewModleResult(ViewModel viewModel, HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {
		String path = viewModel.getViewPath();
		if (StringUtils.isNotEmpty(path)) {
			if (path.startsWith("/")) {
				response.sendRedirect(request.getContextPath() + path);
			} else {
				Map<String, Object> model = viewModel.getModel();
				for (Map.Entry<String, Object> entity : model.entrySet()) {
					request.setAttribute(entity.getKey(), entity.getValue());
				}
				request.getRequestDispatcher(Global.getAppJspPath() + path).forward(request, response);
			}
		}
	}

	/**
	 * 返回 Json数据
	 * 
	 * @param data
	 * @param response
	 * @throws IOException
	 */
	private void handleRtnDataResult(RtnData data, HttpServletResponse response) throws IOException {
		Object model = data.getModel();
		if (null != model) {
			response.setContentType("application/json");
			response.setCharacterEncoding("UTF-8");
			PrintWriter write = response.getWriter();
			String json = JsonUtil.toJson(model);
			write.write(json);
			write.flush();
			write.close();
		}
	}
}
